//---------------------------------------------------------------------------
#include <windows.h>

#include "exp_api.h"
//---------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    return TRUE;
}
//---------------------------------------------------------------------------
int __stdcall GetPluginInfo (int infono, char *buf, int buflen)
{
    char *infomation[] = {
      /* 0 */  "T0XN",
      /* 1 */  "BMP export library v0.0.3.0 by 43T",
      /* 2 */  "BMP",
      /* 3 */  ".bmp",
    };

    if (infono < 0 || infono >= (sizeof(infomation) / sizeof(char *))) 
        return 0;

    lstrcpyn(buf, infomation[infono], buflen);

    return lstrlen(buf);
}
//---------------------------------------------------------------------------
int __stdcall IsSupported (int colorDepth)
{
    int ret = 0;
    /* 色深度を確認 */
    if (   colorDepth == 1
        || colorDepth == 4
        || colorDepth == 8
        || colorDepth == 16
        || colorDepth == 24
        || colorDepth == 32
       ) {
            ret = 1;
    }

    return ret;
}
//---------------------------------------------------------------------------
int __stdcall CreatePicture (
                char *filepath, unsigned int flag,
                HANDLE *pHBInfo, HANDLE *pHBm, PictureInfo *lpInfo,
    int (CALLBACK *lpPrgressCallback)(int,int,long),
                long lData)
{
    BITMAPFILEHEADER bmp_h;
    BITMAPINFOHEADER *pbmih;
    char *bmp_image;
    char *bmp_info;
    int ret = XPI_ALL_RIGHT;
    HANDLE hf;
    DWORD wbyte;
    unsigned int linesize;
    unsigned int srcbmisize;

#if 0
    if (lpPrgressCallback != NULL)
        if (lpPrgressCallback(0, 1, lData)) //0%
            return XPI_ABORT;
#endif

    /* flag check */
	switch (flag) {
		case 0: //メモリハンドル
		    pbmih = (BITMAPINFOHEADER *)LocalLock(*pHBInfo);
			bmp_image = (char *)LocalLock(*pHBm);
			break;
		case 1: //メモリのアドレス
		    pbmih = (BITMAPINFOHEADER *)pHBInfo;
			bmp_image = (char *)pHBm;
			break;
		default:
    	return XPI_NO_FUNCTION;
	}


    /*bmpヘッダ作成*/
    bmp_h.bfType      = 0x4d42; /*"BM"*/
    //bmp_h.bfSize      = 0; //後で入れる
    bmp_h.bfReserved1 = 0; /*must be 0*/
    bmp_h.bfReserved2 = 0; /*must be 0*/

    bmp_h.bfOffBits = sizeof(BITMAPFILEHEADER) +pbmih->biSize;
    linesize = pbmih->biWidth;
    srcbmisize = pbmih->biSize;
    switch (pbmih->biBitCount) {
        case 1:
            bmp_h.bfOffBits += sizeof(RGBQUAD)*2;
            srcbmisize += sizeof(RGBQUAD)*2;
            linesize = (linesize +7) >> 3;
            break;
        case 4:
            bmp_h.bfOffBits += sizeof(RGBQUAD)*16;
            srcbmisize += (pbmih->biClrUsed)? sizeof(RGBQUAD) * pbmih->biClrUsed: sizeof(RGBQUAD)*16;
            linesize = (linesize +1) >> 1;
            break;
        case 8:
            bmp_h.bfOffBits += sizeof(RGBQUAD)*256;
            srcbmisize += (pbmih->biClrUsed)? sizeof(RGBQUAD) * pbmih->biClrUsed: sizeof(RGBQUAD)*256;
            //linesize = linesize;
            break;
        case 16:
            //マスクがあるか
            if (pbmih->biCompression == BI_BITFIELDS) {
                bmp_h.bfOffBits += sizeof(DWORD)*3;
                srcbmisize += sizeof(DWORD)*3;
            }
            linesize = linesize * 2;
            break;
        case 24:
            linesize = linesize * 3;
            break;
        case 32:
            //マスクがあるか
            if (pbmih->biCompression == BI_BITFIELDS) {
                bmp_h.bfOffBits += sizeof(DWORD)*3;
                srcbmisize += sizeof(DWORD)*3;
            }
            linesize = linesize * 4;
            break;
        default:
            //知らない
            ret = XPI_NOT_SUPPROT;
            goto ERR_EXIT;
    }

    //次のは0にセットしちゃう
    pbmih->biXPelsPerMeter = 0;
    pbmih->biYPelsPerMeter = 0;
    pbmih->biClrUsed = 0;
    pbmih->biClrImportant = 0;

    //イメージサイズは計算しなおす
    pbmih->biSizeImage = ((linesize +3) & ~3) * abs(pbmih->biHeight);
    bmp_h.bfSize = bmp_h.bfOffBits + pbmih->biSizeImage;

    bmp_info = (char*)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, bmp_h.bfOffBits);
    if (bmp_info == NULL) {
        ret = XPI_NO_MEMORY;
        goto ERR_EXIT;
    }
    CopyMemory(bmp_info, &bmp_h, sizeof(bmp_h));
    CopyMemory(bmp_info +sizeof(bmp_h), pbmih, srcbmisize);

    hf = CreateFile(filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
if (hf != INVALID_HANDLE_VALUE) {
    if (WriteFile(hf, bmp_info, bmp_h.bfOffBits, &wbyte, NULL) == 0) {
        ret = XPI_FILE_WRITE_ERROR;
    } else if (WriteFile(hf, bmp_image, pbmih->biSizeImage, &wbyte, NULL) == 0) {
        ret = XPI_FILE_WRITE_ERROR;
    }
    CloseHandle(hf);
} else {
    ret = XPI_FILE_WRITE_ERROR;
}

    LocalFree(bmp_info);
ERR_EXIT:
	switch (flag) {
		case 0: //メモリハンドル
		    LocalUnlock(*pHBInfo);
			LocalUnlock(*pHBm);
			break;
		case 1: //メモリのアドレス
			break;
	}

#if 0
    if (lpPrgressCallback != NULL)
        if (lpPrgressCallback(1, 1, lData)) //100%
            return XPI_ABORT;
#endif

    return ret;
}
//---------------------------------------------------------------------------
int __stdcall ConfigurationDlg(HWND parent, int fnc)
{
    return XPI_NO_FUNCTION;
}
//---------------------------------------------------------------------------
